﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Entity.ProcessResultEntity
{
    /// <summary>
    /// RoomType的信息需要提前载入
    /// </summary>
    [Serializable]
    public class ProcessResultHotelEntity : ICloneable
    {
        public bool IsSupportMultiDay { get; set; }

        public OverseaEnum IsOversea { get; set; }

        public int City { get; set; }

        public int Hotel { get; set; }

        public string HotelGroupHotelCode { get; set; }

        public DateTime Arrival { get; set; }

        public DateTime Departure { get; set; }

        public List<RoomAllInfoEntity> RoomInfoList { get; set; }

        public StatusDataEntity StatusEntity { get; set; }

        public bool CompareTo(ProcessResultHotelEntity newResult)
        {
            if (newResult == null) return false;
            if (this.Arrival != newResult.Arrival) return false;
            if (this.Departure != newResult.Departure) return false;
            if (this.Hotel != newResult.Hotel) return false;
            if (this.HotelGroupHotelCode != newResult.HotelGroupHotelCode) return false;
            if (this.RoomInfoList.Count != newResult.RoomInfoList.Count) return false;
            foreach (var room in this.RoomInfoList)
            {
                foreach (var room2 in newResult.RoomInfoList)
                {
                    if (room.Room == room2.Room)
                    {
                        if (!room.RoomPolicy.CompareTo(room2.RoomPolicy)) return false;
                        foreach (var price in room.RoomPrice)
                        {
                            foreach (var price2 in room2.RoomPrice)
                            {
                                if (price.EffectDate == price2.EffectDate)
                                {
                                    if (!price.CompareTo(price2)) return false;
                                }
                            }
                        }
                    }
                }
            }

            return true;
        }

        public object Clone()
        {
            ProcessResultHotelEntity copy = new ProcessResultHotelEntity();
            copy.Arrival = Arrival;
            copy.City = City;
            copy.Departure = Departure;
            copy.Hotel = Hotel;
            copy.HotelGroupHotelCode = HotelGroupHotelCode;
            copy.IsOversea = IsOversea;
            copy.IsSupportMultiDay = IsSupportMultiDay;
            copy.RoomInfoList = new List<RoomAllInfoEntity>();
            copy.StatusEntity = new StatusDataEntity();
            foreach (var room in RoomInfoList)
            {
                copy.RoomInfoList.Add(new RoomAllInfoEntity()
                {
                    Room = room.Room,
                    RoomQuantity = new RoomQuantityEntity(),
                    RoomTypeCode = room.RoomTypeCode,
                    RatePlanCode = room.RatePlanCode,
                    RatePlanCategory = room.RatePlanCategory,
                    RoomPolicy = room.RoomPolicy != null ? new RoomPolicyEntity()
                    {
                        Lct = room.RoomPolicy.Lct,
                        CancelPolicyList = room.RoomPolicy.CancelPolicyList,
                        DeductType = room.RoomPolicy.DeductType,
                        PaymentType = room.RoomPolicy.PaymentType,
                        GuaranteeType = room.RoomPolicy.GuaranteeType,
                        LastReserveTimeHour = room.RoomPolicy.LastReserveTimeHour,
                        RoomStatus = room.RoomPolicy.RoomStatus
                    } : new RoomPolicyEntity(),
                    DefaultValue = room.DefaultValue != null ? new RoomTypeDefaultEntity()
                    {
                        Def_DeductType = room.DefaultValue.Def_DeductType,
                        Def_LateReserveTime = room.DefaultValue.Def_LateReserveTime,
                        Def_Recommend = room.DefaultValue.Def_Recommend,
                        Def_Recommend_intl = room.DefaultValue.Def_Recommend_intl,
                        Def_RoomPerson = room.DefaultValue.Def_RoomPerson,
                        Def_Currency = room.DefaultValue.Def_Currency,
                    } : new RoomTypeDefaultEntity(),
                    RoomPrice = new List<RoomPriceEntity>()
                });

            }
            return copy;
        }
    }

    public enum OverseaEnum
    {
        OVERSEA,
        DOMESTIC
    }

    [Serializable]
    public class RoomAllInfoEntity
    {
        public int Room { get; set; }

        public string RoomTypeCode { get; set; }

        public string RatePlanCode { get; set; }

        public string RatePlanCategory { get; set; }

        public RoomPolicyEntity RoomPolicy { get; set; }

        /// <summary>
        /// 存每一天的价格 EffectDate来区分
        /// </summary>
        public List<RoomPriceEntity> RoomPrice { get; set; }

        public RoomQuantityEntity RoomQuantity { get; set; }

        public RoomTypeDefaultEntity DefaultValue { get; set; }
    }

    [Serializable]
    public class RoomPriceEntity
    {
        public DateTime EffectDate { get; set; }

        public double PriceAfterTax { get; set; }

        public double Cost { get; set; }

        public double PriceBeforeTax { get; set; }

        public double Tax { get; set; }

        public double Fee { get; set; }

        public string CurrencyCode { get; set; }

        public int MealNumber { get; set; }

        public MealType MealType { get; set; }

        public bool CompareTo(RoomPriceEntity price)
        {
            return this.EffectDate == price.EffectDate
                && this.PriceAfterTax == price.PriceAfterTax
                && this.Cost == price.Cost
                && this.PriceBeforeTax == price.PriceBeforeTax
                && this.Tax == price.Tax
                && this.Fee == price.Fee
                && this.CurrencyCode == price.CurrencyCode
                && this.MealNumber == price.MealNumber
                && this.MealType == price.MealType;
        }
    }

    public enum MealType
    {
        BB = 0,
        HB = 1,
        FB = 2,
    }

    [Serializable]
    public class RoomQuantityEntity
    {
        public int AvailRoomQuantity { get; set; }
    }

    [Serializable]
    public class RoomTypeDefaultEntity
    {
        /// <summary>
        /// 推荐级别 Online
        /// </summary>
        public int Def_Recommend { get; set; }

        /// <summary>
        /// 推荐级别 英文网站
        /// </summary>
        public int Def_Recommend_intl { get; set; }

        /// <summary>
        /// 担保方式 F：First C：全额
        /// </summary>
        public string Def_DeductType { get; set; }

        /// <summary>
        /// 最晚预订时间
        /// </summary>
        public int Def_LateReserveTime { get; set; }

        /// <summary>
        /// 最大可入住人数
        /// </summary>
        public int Def_RoomPerson { get; set; }

        /// <summary>
        /// 房型上落地的Currency
        /// </summary>
        public string Def_Currency { get; set; }
    }

    [Serializable]
    public class RoomPolicyEntity
    {
        /// <summary>
        /// 房态
        /// </summary>
        public string RoomStatus { get; set; }
        /// <summary>
        /// 担保规则
        /// </summary>
        public string GuaranteeType { get; set; }
        /// <summary>
        /// 应该在对方接口里没有
        /// </summary>
        public int LastReserveTimeHour { get; set; }

        /// <summary>
        /// Last Cancel Time最晚取消时间
        /// </summary>
        public int Lct { get; set; }

        /// <summary>
        /// F 首日， C 全额
        /// </summary>
        public string DeductType { get; set; }

        /// <summary>
        /// 支付方式
        /// </summary>
        public PaymentType PaymentType { get; set; }
        /// <summary>
        /// 暂时不用
        /// </summary>
        public List<CancelPolicyEntity> CancelPolicyList { get; set; }

        public bool CompareTo(RoomPolicyEntity policy)
        {
            return this.RoomStatus == policy.RoomStatus && this.GuaranteeType == policy.GuaranteeType
                && this.DeductType == policy.DeductType
                && this.LastReserveTimeHour == policy.LastReserveTimeHour
                && this.Lct == policy.Lct
                && this.PaymentType == policy.PaymentType;
        }
    }

    public class StatusDataEntity
    {
        /// <summary>
        /// 下载或者处理的时间
        /// </summary>
        public long Duration { get; set; }

        public StatusType StatusFlag { get; set; }

        public string Msg { get; set; }
    }

    public enum PaymentType
    {
        FG, PP, PKG, HF, OTHER
    }

    public enum StatusType
    {
        NormalSuccess,
        RetrySuccess,
        Failed,
        Expired,
        LongTimeSuccess,
    }

    [Serializable]
    public class CancelPolicyEntity
    {
        /// <summary>
        /// 当地时间
        /// </summary>
        public DateTime BeforeThisTime { get; set; }

        public double? CancelFeePenalty { get; set; }

        public double? CancelPercentPenalty { get; set; }

        public int? CancelNightPenalty { get; set; }
    }
}
